#include "md_object_3d.h"
#include <cmath>
#include "md_log.h"

namespace asha {
namespace vrlib {

MDObject3D::MDObject3D() {
}

MDObject3D::~MDObject3D() {
    Destroy();
}

void MDObject3D::LoadSphere() {
    // 默认参数: radius=18, rings=75, sectors=150 (参考 MDSphere3D.java)
    // 注意：这里 radius 可以设为 1.0f，通过矩阵缩放，或者保持原值
    // Java代码中是 generateSphere(18,75,150,object3D);
    GenerateSphere(18.0f, 75, 150);
}

void MDObject3D::GenerateSphere(float radius, int rings, int sectors) {
    const float PI = 3.14159265358979323846f;
    const float PI_2 = PI / 2.0f;

    float R = 1.0f / (float)rings;
    float S = 1.0f / (float)sectors;
    
    int numPoint = (rings + 1) * (sectors + 1);
    
    vertices_.resize(numPoint * 3);
    texcoords_.resize(numPoint * 2);
    indices_.resize(rings * sectors * 6);

    int t = 0, v = 0;
    for(int r = 0; r < rings + 1; r++) {
        for(int s = 0; s < sectors + 1; s++) {
            float x = (float) (cos(2*PI * s * S) * sin( PI * r * R ));
            float y = - (float) sin( -PI_2 + PI * r * R );
            float z = (float) (sin(2*PI * s * S) * sin( PI * r * R ));

            texcoords_[t++] = s*S;
            texcoords_[t++] = 1 - r*R;

            vertices_[v++] = x * radius;
            vertices_[v++] = y * radius;
            vertices_[v++] = z * radius;
        }
    }

    int counter = 0;
    int sectorsPlusOne = sectors + 1;
    for(int r = 0; r < rings; r++){
        for(int s = 0; s < sectors; s++) {
            indices_[counter++] = (short) (r * sectorsPlusOne + s);       //(a)
            indices_[counter++] = (short) ((r+1) * sectorsPlusOne + (s));    //(b)
            indices_[counter++] = (short) ((r) * sectorsPlusOne + (s+1));  // (c)
            indices_[counter++] = (short) ((r) * sectorsPlusOne + (s+1));  // (c)
            indices_[counter++] = (short) ((r+1) * sectorsPlusOne + (s));    //(b)
            indices_[counter++] = (short) ((r+1) * sectorsPlusOne + (s+1));  // (d)
        }
    }
    
    num_indices_ = indices_.size();
}

void MDObject3D::UploadData() {
    if (vertices_.empty()) return;

    if (vbo_vertices_ == 0) {
        glGenBuffers(1, &vbo_vertices_);
        glGenBuffers(1, &vbo_texcoords_);
        glGenBuffers(1, &ibo_indices_);
    }

    glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_);
    glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(float), vertices_.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords_);
    glBufferData(GL_ARRAY_BUFFER, texcoords_.size() * sizeof(float), texcoords_.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof(short), indices_.data(), GL_STATIC_DRAW);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    
    data_uploaded_ = true;
}

void MDObject3D::Draw() {
    if (!data_uploaded_) {
        UploadData();
    }
    
    if (vbo_vertices_ == 0) return;

    // 绑定 VBO
    glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_);
    // 假设 layout 0 是 position
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoords_);
    // 假设 layout 1 是 texCoord
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices_);
    glDrawElements(GL_TRIANGLES, num_indices_, GL_UNSIGNED_SHORT, 0);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void MDObject3D::Destroy() {
    if (vbo_vertices_ != 0) {
        glDeleteBuffers(1, &vbo_vertices_);
        vbo_vertices_ = 0;
    }
    if (vbo_texcoords_ != 0) {
        glDeleteBuffers(1, &vbo_texcoords_);
        vbo_texcoords_ = 0;
    }
    if (ibo_indices_ != 0) {
        glDeleteBuffers(1, &ibo_indices_);
        ibo_indices_ = 0;
    }
    data_uploaded_ = false;
}

}
}
